package com.apache.uct.common;

import java.util.Iterator;
import java.util.Map;

public class AuthUtil {

    private static final char splitChar = '/';

    /**
     * 用户是否拥有访问当前资源的权限.当前资源的权限是定义在资源库中的
     *
     * @param loginUser
     * @return
     */
    public static boolean canAccess(String actFullEname, String lockType, LoginUser loginUser) {
        Map keyMap = loginUser.getActMap();
        if (actFullEname == null || "".equals(actFullEname.trim())) {
            return true;
        }

        //如果是严格锁
        if ("Strick".equals(lockType)) {
            if (strictLock(actFullEname, keyMap)) {
                return true;
            } else {
                return false;
            }
        }

        //如果是子孙锁
        if ("Child".equals(lockType)) {
            if (childLock(actFullEname, keyMap)) {
                return true;
            } else {
                return false;
            }
        }

        //如果是父辈锁
        if ("Father".equals(lockType)) {
            if (fatherLock(actFullEname, keyMap)) {
                return true;
            } else {
                return false;
            }
        }

        //如果是家族锁
        if ("Family".equals(lockType)) {
            if (familyLock(actFullEname, keyMap)) {
                return true;
            } else {
                return false;
            }
        }
        return false;

    }

    /**
     * 打开严格锁
     *
     * @param key
     * @return
     */
    public static boolean openStrictLock(String key, LoginUser loginUser) {
        //return strictLock(key,loginUser.getKeyMap());
        return strictLock(key, loginUser.getActMap());
    }

    /**
     * 打开父辈锁
     *
     * @param key
     * @return
     */
    public static boolean openFatherLock(String key, LoginUser loginUser) {
        return fatherLock(key, loginUser.getActMap());
    }

    /**
     * 打开子孙锁
     *
     * @param key
     * @return
     */
    public static boolean openChildLock(String key, LoginUser loginUser) {
        return childLock(key, loginUser.getActMap());
    }

    /**
     * 家族锁
     *
     * @param key
     * @return
     */
    public static boolean openFamillyLock(String key, LoginUser loginUser) {
        return familyLock(key, loginUser.getActMap());
    }

    /**
     * 严格锁:全路径(含自身)
     *
     * @param key 该锁的钥匙
     * @param keyMap 开锁者拥有的钥匙串
     * @return 能否打开锁，true:能,false：不能。
     */
    private static boolean strictLock(String key, Map keyMap) {
        if (isInValidKey(key))
            return true;
        if (null != keyMap && keyMap.containsKey("/"))
            return true;
        return null == keyMap ? false : keyMap.containsKey(key);
    }

    /**
     * 父辈锁:部分前端路径匹配(含自身)
     *
     * @param key 该锁的钥匙
     * @param keyMap 开锁者拥有的钥匙串
     * @return 能否打开锁，true:能,false：不能。
     */
    private static boolean fatherLock(String key, Map keyMap) {
        if (isInvalidkeyMap(keyMap))
            return false;
        if (null != keyMap && keyMap.containsKey("/"))
            return true;

        while (true) {
            if (strictLock(key, keyMap)) {
                return true;
            }
            int index = key.lastIndexOf(splitChar);
            if (index < 1) {
                return false;
            }
            key = key.substring(0, index);
        }
    }

    /**
     * 子孙锁：全部前端路径匹配(含自身)
     *
     * @param key 该锁的钥匙
     * @param keyMap 开锁者拥有的钥匙串
     * @return 能否打开锁，true:能,false：不能。
     */
    @SuppressWarnings("rawtypes")
    private static boolean childLock(String key, Map keyMap) {
        if (isInValidKey(key))
            return true;
        if (isInvalidkeyMap(keyMap))
            return false;
        if (null != keyMap && keyMap.containsKey("/"))
            return true;

        Iterator it = keyMap.keySet().iterator();
        while (it.hasNext()) {
            if (String.valueOf(it.next()).indexOf(key) == 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * 家族锁：部分路径匹配(含自身)
     *
     * @param key 该锁的钥匙
     * @param keyMap 开锁者拥有的钥匙串
     * @return 能否打开锁，true:能,false：不能。
     */
    private static boolean familyLock(String key, Map keyMap) {
        return fatherLock(key, keyMap) || childLock(key, keyMap);
    }

    private static boolean isInValidKey(String key) {
        return null == key || "".equals(key.trim());
    }

    private static boolean isInvalidkeyMap(Map keyMap) {
        return null == keyMap || keyMap.isEmpty();
    }
}
